home *** CD-ROM | disk | FTP | other *** search
Text File | 1999-06-25 | 7.6 KB | 274 lines | [TEXT/CWIE] |
- // ===========================================================================
- // CPongGameBehavior.cp ©1999 Eric Traut
- // ===========================================================================
-
- #include "CPongGameBehavior.h"
- #include "CShadowWindow.h"
-
-
- PicHandle CPongGameBehavior::sLeftPaddlePICT = NULL;
- PicHandle CPongGameBehavior::sRightPaddlePICT = NULL;
- CIconHandle CPongGameBehavior::sBallIcon = NULL;
- SndChannelPtr CPongGameBehavior::sSoundChannel = NULL;
- SndListHandle CPongGameBehavior::sBootBeepSound = NULL;
- SndListHandle CPongGameBehavior::sBootCrashSound = NULL;
-
-
- // ---------------------------------------------------------------------------
- // • CPongGameBehavior
- // ---------------------------------------------------------------------------
-
- CPongGameBehavior::CPongGameBehavior(
- CShadowWindow & inShadowWindow)
- : COffscreenBehavior(inShadowWindow, true, true)
- {
- mCurGameState = kPongGameStartState;
- }
-
-
- // ---------------------------------------------------------------------------
- // • GetTicksForState
- // ---------------------------------------------------------------------------
-
- void
- CPongGameBehavior::DoIdleTask(
- Boolean inGNETime)
- {
- if (inGNETime && mCurGameState == kPongGameStateTearDown)
- {
- // Detach ourselves
- mShadowWindow.DetachBehavior();
- }
- else
- {
- COffscreenBehavior::DoIdleTask(inGNETime);
- }
- }
-
-
- // ---------------------------------------------------------------------------
- // • RenderToGWorld
- // ---------------------------------------------------------------------------
-
- Boolean
- CPongGameBehavior::RenderToGWorld(
- StGWorldLocker & inBackingLocker,
- StGWorldLocker & inRenderingLocker)
- {
- #pragma unused (inBackingLocker, inRenderingLocker)
-
- // Start by copying the entire window (so we get the scroll bars, etc.)
- (void) COffscreenBehavior::RenderToGWorld(inBackingLocker, inRenderingLocker);
-
- UInt32 curTicks = ::TickCount();
- Rect windowContentRect;
- Rect leftPaddleRect;
- Rect rightPaddleRect;
- Rect ballRect;
- Rect dummyRect;
-
- windowContentRect.top = mGWorldRect.top + 21;
- windowContentRect.bottom = mGWorldRect.bottom - 15;
- windowContentRect.left = mGWorldRect.left;
- windowContentRect.right = mGWorldRect.right - 15;
-
- ThrowIfNULL_(sLeftPaddlePICT);
- ThrowIfNULL_(sRightPaddlePICT);
- ThrowIfNULL_(sBallIcon);
- ThrowIfNULL_(sBootBeepSound);
- ThrowIfNULL_(sBootCrashSound);
- ThrowIfNULL_(sSoundChannel);
-
- // Erase the old background of the scrolling content area
- ::BackColor(whiteColor);
- ::EraseRect(&windowContentRect);
-
- switch (mCurGameState)
- {
- case kPongGameStartState:
- // Set up the initial state of the game
- mBallLoc.h = (windowContentRect.left + windowContentRect.right) / 2;
- mBallLoc.v = (windowContentRect.top + windowContentRect.bottom) / 2;
- mBallVector.h = -3;
- mBallVector.v = -1;
- mColliding = false;
-
- mLeftPaddleVDelta = 0;
- mRightPaddleVDelta = 0;
-
- mLeftPaddleVHeight = 0;
- mRightPaddleVHeight = 0;
-
- mCurGameState = kPongGameStatePlaying;
- break;
-
- case kPongGameStatePlaying:
- leftPaddleRect.left = 7;
- leftPaddleRect.top = mLeftPaddleVHeight + 21;
- leftPaddleRect.right = leftPaddleRect.left + sLeftPaddlePICT[0]->picFrame.right - sLeftPaddlePICT[0]->picFrame.left;
- leftPaddleRect.bottom = leftPaddleRect.top + sLeftPaddlePICT[0]->picFrame.bottom - sLeftPaddlePICT[0]->picFrame.top;
-
- rightPaddleRect.right = windowContentRect.right - 8;
- rightPaddleRect.top = mRightPaddleVHeight + 23;
- rightPaddleRect.left = rightPaddleRect.right - sRightPaddlePICT[0]->picFrame.right + sRightPaddlePICT[0]->picFrame.left;
- rightPaddleRect.bottom = rightPaddleRect.top + sRightPaddlePICT[0]->picFrame.bottom - sRightPaddlePICT[0]->picFrame.top;
-
- // Draw the two paddles
- ::DrawPicture(sLeftPaddlePICT, &leftPaddleRect);
- ::DrawPicture(sRightPaddlePICT, &rightPaddleRect);
-
- // Draw the ball
- ballRect.top = mBallLoc.v - 8;
- ballRect.bottom = mBallLoc.v + 8;
- ballRect.left = mBallLoc.h - 8;
- ballRect.right = mBallLoc.h + 8;
- ::PlotCIcon(&ballRect, sBallIcon);
-
- if (mLastUpdateTicks != curTicks)
- {
- // Update the paddle location
- mLeftPaddleVHeight += mLeftPaddleVDelta;
- mRightPaddleVHeight += mRightPaddleVDelta;
-
- if (mLeftPaddleVHeight < 0)
- mLeftPaddleVHeight = 0;
- else if (mLeftPaddleVHeight > windowContentRect.bottom - (sLeftPaddlePICT[0]->picFrame.bottom - sLeftPaddlePICT[0]->picFrame.top) - 24)
- mLeftPaddleVHeight = windowContentRect.bottom - (sLeftPaddlePICT[0]->picFrame.bottom - sLeftPaddlePICT[0]->picFrame.top) - 24;
- if (mRightPaddleVHeight < 0)
- mRightPaddleVHeight = 0;
- else if (mRightPaddleVHeight > windowContentRect.bottom - (sRightPaddlePICT[0]->picFrame.bottom - sRightPaddlePICT[0]->picFrame.top) - 24)
- mRightPaddleVHeight = windowContentRect.bottom - (sRightPaddlePICT[0]->picFrame.bottom - sRightPaddlePICT[0]->picFrame.top) - 24;
-
- mLeftPaddleVDelta = 0;
- mRightPaddleVDelta = 0;
-
- // Update the ball location
- mBallLoc.h += mBallVector.h;
- mBallLoc.v += mBallVector.v;
-
- // Check for game-over conditions
- if (mBallLoc.h < 8 ||
- mBallLoc.h > windowContentRect.right - 8)
- {
- (void) ::SndPlay(sSoundChannel, sBootCrashSound, true);
- mCurGameState = kPongGameStateTearDown;
- }
- // Check for top/bottom collisions
- if (mBallLoc.v < 21 + 8 ||
- mBallLoc.v > windowContentRect.bottom - 8)
- {
- mBallVector.v = -mBallVector.v;
- }
- // Check for paddle collisions
- else if (::SectRect(&ballRect, &leftPaddleRect, &dummyRect) ||
- ::SectRect(&ballRect, &rightPaddleRect, &dummyRect))
- {
- if (!mColliding)
- {
- SInt32 newHSpeed = (::Random() + 0x7FFF) % 5;
- if (newHSpeed <= 1)
- newHSpeed = 3;
-
- SInt32 newVSpeed = ::Random() % 3;
-
- (void) ::SndPlay(sSoundChannel, sBootBeepSound, true);
- if (mBallVector.h > 0)
- mBallVector.h = -newHSpeed;
- else
- mBallVector.h = newHSpeed;
-
- mBallVector.v = newVSpeed;
- mColliding = true;
- }
- }
- else
- {
- mColliding = false;
- }
-
- mLastUpdateTicks = curTicks;
- }
- break;
-
- case kPongGameStateTearDown:
-
- break;
- }
-
- return true;
- }
-
-
- // ---------------------------------------------------------------------------
- // • Initialize [static]
- // ---------------------------------------------------------------------------
-
- void
- CPongGameBehavior::Initialize(
- SndChannelPtr inSoundChannel)
- {
- sLeftPaddlePICT = ::GetPicture(131);
- Assert_(sLeftPaddlePICT != NULL);
-
- sRightPaddlePICT = ::GetPicture(132);
- Assert_(sRightPaddlePICT != NULL);
-
- sBallIcon = ::GetCIcon(128);
- Assert_(sBallIcon != NULL);
-
- sSoundChannel = inSoundChannel;
-
- sBootBeepSound = reinterpret_cast<SndListHandle>(::Get1Resource('snd ', 130));
- Assert_(sBootBeepSound != NULL);
-
- sBootCrashSound = reinterpret_cast<SndListHandle>(::Get1Resource('snd ', 129));
- Assert_(sBootCrashSound != NULL);
- }
-
-
- // ---------------------------------------------------------------------------
- // • HandleEvent
- // ---------------------------------------------------------------------------
-
- void
- CPongGameBehavior::HandleEvent(
- EventRecord * ioEvent,
- Boolean * ioResult)
- {
- if (ioEvent->what == keyDown ||
- ioEvent->what == autoKey)
- {
- if ((ioEvent->modifiers & cmdKey) == 0)
- {
- // Swallow any key events
- *ioResult = false;
-
- UInt8 character = ioEvent->message & charCodeMask;
- if (character >= 'a' && character <= 'z')
- character += 'A' - 'a';
-
- switch (character)
- {
- case 'W':
- mLeftPaddleVDelta -= 5;
- break;
-
- case 'S':
- mLeftPaddleVDelta += 5;
- break;
-
- case 'I':
- mRightPaddleVDelta -= 5;
- break;
-
- case 'K':
- mRightPaddleVDelta += 5;
- break;
- }
- }
- }
- }
-
-
-
-